home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
Games
/
xmine
/
xmine.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
38KB
|
1,488 lines
/* xmine - Copyright (c) 1993 by Paul Falstad
* freely redistributable
*/
#include <stdio.h>
#include <Xm/MainW.h>
#include <Xm/DrawingA.h>
#include <Xm/PushBG.h>
#include <Xm/PushB.h>
#include <Xm/RowColumn.h>
#include <Xm/ScrolledW.h>
#include <Xm/Form.h>
#include <Xm/CascadeBG.h>
#include <Xm/Separator.h>
#include <Xm/ToggleB.h>
#include <Xm/DialogS.h>
#include <Xm/TextF.h>
#include <Xm/LabelG.h>
#include <Xm/PanedW.h>
#include "patchlevel.h"
#define GSPACEX 16
#define GSPACEY 16
#define SCORE_FILE "~/.xmine_scores"
#define TOPMARGIN 60
#define BOTMARGIN 12
#define SIDEMARGIN 12
#define STATUS_Y_OFFSET 12
#define TOTAL_WIDTH (SIDEMARGIN*2+gsizex*GSPACEX)
#define TOTAL_HEIGHT (TOPMARGIN+BOTMARGIN+gsizey*GSPACEY)
#define STATUS_HEIGHT (TOPMARGIN-STATUS_Y_OFFSET*2)
#define DIGIT_X_OFFSET (SIDEMARGIN+4)
#define DIGIT_Y_OFFSET (STATUS_Y_OFFSET+4)
#define DIGIT_HEIGHT (TOPMARGIN-DIGIT_Y_OFFSET*2)
#define DIGIT_WIDTH 16
#define DIGIT_COUNT 3
#define DIGIT_MARGIN 2
#define DIGIT_HWEDGE_WIDTH (DIGIT_WIDTH-(DIGIT_MARGIN+1)*2)
#define DIGIT_VWEDGE_HEIGHT ((DIGIT_HEIGHT-7)/2)
#define COVERED 0
#define MARKED 1
#define UNCOVERED 2
#define QUESTIONED 3
#define MINE -1
#define MAX_GSIZEX 100
#define MAX_GSIZEY 100
int grid[MAX_GSIZEX][MAX_GSIZEY]; /* fix this */
int gridview[MAX_GSIZEX][MAX_GSIZEY]; /* fix this */
#define INITIAL_SIZE_X 8
#define INITIAL_SIZE_Y 8
int gsizex = INITIAL_SIZE_X, gsizey = INITIAL_SIZE_Y;
int layed_out = 0, game_on = 1, face_armed = 0;
int questions_allowed = 0, game_level = 0;
XFontStruct *font_info;
Widget drawarea;
Display *disp;
Window win;
#define COL_BLUE 0
#define COL_LIMEGREEN 1
#define COL_RED 2
#define COL_NAVY 3
#define COL_BROWN 4
#define COL_AQUA 5
#define COL_BLACK 6
#define COL_GRAY 7
#define COL_WHITE 8
#define COL_LITEGRAY 9
#define COL_DARKGRAY 10
#define COL_YELLOW 11
#define COL_DARKRED 12
#define COL_COUNT 13
char *colnames[COL_COUNT] = {
"Blue", "LimeGreen", "Red", "Navy",
"Brown", "MediumAquamarine", "Black", "Gray",
"White", "Grey75", "Grey50", "Yellow", "darkred"
};
XColor cols[COL_COUNT];
int numcols[] = {
COL_BLUE, COL_LIMEGREEN, COL_RED, COL_NAVY,
COL_BROWN, COL_AQUA, COL_BLACK, COL_GRAY
};
#include "cool.xbm"
#include "fillface.xbm"
#include "dead.xbm"
#include "happy.xbm"
#include "ohno.xbm"
#include "press.xbm"
#define FACE_HAPPY 0
#define FACE_OHNO 1
#define FACE_COOL 2
#define FACE_DEAD 3
#define FACE_PRESS 4
#define FACE_COUNT 5
Pixmap faces[FACE_COUNT];
static char *face_bits[FACE_COUNT] = {
happy_bits, ohno_bits, cool_bits, dead_bits, press_bits
};
int cur_face = FACE_HAPPY;
int mine_count, covered_count, marked_count;
int armed_x, armed_y, armed, timer;
XtIntervalId timer_id;
#define FACE_BUTTON_WIDTH (fillface_width+5)
#define FACE_BUTTON_HEIGHT (fillface_height+5)
#define FACE_X_POS ((TOTAL_WIDTH-FACE_BUTTON_WIDTH)/2+1)
#define FACE_Y_POS ((TOPMARGIN-FACE_BUTTON_HEIGHT)/2)
GC gc;
#ifdef __STDC__
#define P(X) X
#else
#define P(X) ()
#endif /* __STDC__ */
typedef void (*void_proc)();
extern void search_action P ((Widget, XButtonEvent *, String *, int *));
extern void clear_action P ((Widget, XButtonEvent *, String *, int *));
extern void mark_action P ((Widget, XButtonEvent *, String *, int *));
extern void redraw_cb P ((Widget, XtPointer, XmDrawingAreaCallbackStruct *));
extern void redrawsquare P ((int, int));
extern void drawsquare P ((int, int));
extern int hasmine P ((int, int));
extern void uncover P ((int, int));
extern void clear_around P ((int, int));
extern int is_state P ((int, int, int));
extern void shadow_rev_rect P ((int, int, int, int, int));
extern void shadow_rect P ((int, int, int, int, int));
extern XmString genxmstr P ((char *));
extern void layout_board P ((int, int));
extern void boom P ((void));
extern void restart P ((void));
extern void draw_face P ((void));
extern void set_face P ((int));
extern void winner P ((void));
extern void draw_blank_square P ((int, int, int));
extern void draw_button P ((int, int));
extern void arm_clear P ((int, int, int));
extern void track_face P ((int, int, int));
extern void arm_face P ((int));
extern void draw_digit P ((int, int, int));
extern void draw_digits P ((int, int));
extern void timer_callback P ((void));
extern void set_level P ((Widget, int));
extern void tog_question P ((void));
extern void set_custom P ((void));
extern void dialog_ok P ((void));
extern void get_text_int P ((Widget, int *));
extern void best_times P ((void));
extern void about P ((void));
extern struct scores *get_scores P ((void));
extern void write_scores P ((struct scores *));
extern void get_score_file_name P ((char *));
extern void new_best P ((int));
extern void clear_scores P ((void));
extern int cant_write_score_file P ((void));
extern void fix_size P ((void));
extern void relax_size P ((void));
extern void resize_handler P ((Widget, XtPointer, XEvent *, Boolean *));
Pixmap fillface;
XtAppContext app;
Widget toplevel, menubar;
Widget level_buttons[4];
struct scores {
char names[3][80];
int times[3];
};
char *fallbacks[] = {
#include "fallback.h"
NULL
};
main(argc, argv)
unsigned int argc;
char *argv[];
{
Widget main_w, drawing_a, menu, btn;
XGCValues gcv;
void draw(), redraw_cb(), set_color(), exit();
XColor unused;
int i;
XtActionsRec actions[3];
String translations =
"<Btn1Down>: search(down)\n\
<Btn1Up>: search(up)\n\
<Btn1Motion>: search(move)\n\
<Btn2Down>: clear(down)\n\
<Btn2Motion>: clear(move)\n\
<Btn2Up>: clear(up)\n\
<Btn3Down>: mark(down)\n";
toplevel = XtVaAppInitialize(&app, "Xmine", NULL, 0,
&argc, argv, fallbacks, NULL);
main_w = XtVaCreateManagedWidget("main_w",
xmFormWidgetClass, toplevel,
NULL);
menubar = XmCreateMenuBar(main_w, "menubar", NULL, 0);
XtVaSetValues(menubar,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
menu = XmCreatePulldownMenu(menubar, "game_menu", NULL, 0);
XtVaCreateManagedWidget("game",
xmCascadeButtonGadgetClass, menubar,
XmNsubMenuId, menu,
XmNbackground, cols[COL_LITEGRAY].pixel,
NULL);
btn = XtVaCreateManagedWidget("New",
xmPushButtonGadgetClass, menu,
NULL);
XtAddCallback(btn, XmNactivateCallback, (void_proc) restart, 0);
XtVaCreateManagedWidget("_sep1", xmSeparatorWidgetClass, menu, NULL);
level_buttons[0] = btn = XtVaCreateManagedWidget("Beginner",
xmToggleButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNvalueChangedCallback, (void_proc) set_level,
(XtPointer) 1);
level_buttons[1] = btn = XtVaCreateManagedWidget("Intermediate",
xmToggleButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNvalueChangedCallback, (void_proc) set_level,
(XtPointer) 2);
level_buttons[2] = btn = XtVaCreateManagedWidget("Expert",
xmToggleButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNvalueChangedCallback, (void_proc) set_level,
(XtPointer) 3);
level_buttons[3] = btn = XtVaCreateManagedWidget("Custom",
xmToggleButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNvalueChangedCallback, (void_proc) set_custom, NULL);
XtVaCreateManagedWidget("_sep2", xmSeparatorWidgetClass, menu, NULL);
btn = XtVaCreateManagedWidget("Marks",
xmToggleButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNvalueChangedCallback,
(XtPointer) tog_question, NULL);
XtVaCreateManagedWidget("_sep3", xmSeparatorWidgetClass, menu, NULL);
btn = XtVaCreateManagedWidget("Best",
xmPushButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNactivateCallback, (void_proc) best_times, NULL);
btn = XtVaCreateManagedWidget("About",
xmPushButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNactivateCallback, (void_proc) about, NULL);
btn = XtVaCreateManagedWidget("Exit",
xmPushButtonWidgetClass, menu,
NULL);
XtAddCallback(btn, XmNactivateCallback, (void_proc) exit, NULL);
XtManageChild(menubar);
for (i = 0; i != COL_COUNT; i++)
XAllocNamedColor(XtDisplay(main_w),
DefaultColormapOfScreen(XtScreen(main_w)),
colnames[i], &cols[i], &unused);
{
cols[COL_DARKRED].red = 60*256;
cols[COL_DARKRED].green = cols[COL_DARKRED].blue = 0;
XAllocColor(XtDisplay(main_w),
DefaultColormapOfScreen(XtScreen(main_w)),
&cols[COL_DARKRED]);
}
gcv.foreground = cols[COL_WHITE].pixel;
gc = XCreateGC(XtDisplay(main_w),
RootWindowOfScreen(XtScreen(main_w)), GCForeground, &gcv);
actions[0].string = "clear";
actions[0].proc = (void_proc) clear_action;
actions[1].string = "search";
actions[1].proc = (void_proc) search_action;
actions[2].string = "mark";
actions[2].proc = (void_proc) mark_action;
XtAppAddActions(app, actions, 3);
drawing_a = XtVaCreateManagedWidget("drawing_a",
xmDrawingAreaWidgetClass, main_w,
XmNtranslations, XtParseTranslationTable(translations),
XmNwidth, GSPACEX*gsizex+SIDEMARGIN*2,
XmNheight, GSPACEY*gsizey+TOPMARGIN+BOTMARGIN,
XmNresizePolicy, XmNONE, /* remain this a fixed size */
XmNbackground, cols[COL_LITEGRAY].pixel,
XmNtopAttachment,XmATTACH_WIDGET,
XmNtopWidget, menubar,
XmNleftAttachment,XmATTACH_FORM,
XmNrightAttachment,XmATTACH_FORM,
XmNbottomAttachment,XmATTACH_FORM,
NULL);
XtAddCallback(drawing_a, XmNexposeCallback, (void_proc) redraw_cb, NULL);
font_info = XLoadQueryFont(XtDisplay(main_w),
"-*-courier-bold-r-normal-*-*-120-*");
XSetFont(XtDisplay(main_w), gc, font_info->fid);
set_level((Widget) 0, 1);
XtAddEventHandler(drawing_a,
StructureNotifyMask, False, resize_handler, 0);
XtRealizeWidget(toplevel);
fillface = XCreateBitmapFromData(XtDisplay(main_w),
XtWindow(main_w), fillface_bits,
fillface_width, fillface_height);
for (i = 0; i != FACE_COUNT; i++)
faces[i] = XCreateBitmapFromData(XtDisplay(main_w),
XtWindow(main_w), face_bits[i],
fillface_width, fillface_height);
drawarea = drawing_a;
win = XtWindow(drawing_a);
disp = XtDisplay(drawing_a);
XtAppMainLoop(app);
return 0;
}
void
search_action(widget, event, args, num_args)
Widget widget;
XButtonEvent *event;
String *args;
int *num_args;
{
int xg, yg;
track_face(event->x, event->y, *args[0]);
if (!game_on) return;
xg = (event->x-SIDEMARGIN)/GSPACEX;
yg = (event->y-TOPMARGIN)/GSPACEY;
if (!strcmp(args[0], "down")) {
armed = False;
if (!(xg >= 0 && xg < gsizex && yg >= 0 && yg < gsizey))
return;
if (gridview[xg][yg] != COVERED) return;
armed_x = xg; armed_y = yg;
armed = True;
set_face(FACE_OHNO);
draw_blank_square(xg, yg, True);
return;
}
if (!strcmp(args[0], "move")) {
if (xg == armed_x && yg == armed_y) {
if (!armed) {
set_face(FACE_OHNO);
draw_blank_square(armed_x, armed_y, True);
armed = True;
}
} else {
if (armed) {
set_face(FACE_HAPPY);
draw_button(armed_x, armed_y);
armed = False;
}
}
return;
}
if (!armed) return;
if (!layed_out) layout_board(armed_x, armed_y);
uncover(armed_x, armed_y);
if (game_on) set_face(FACE_HAPPY);
}
void
track_face(x, y, op)
int x, y, op;
{
int onface = False;
if (x >= FACE_X_POS && x <= FACE_X_POS+FACE_BUTTON_WIDTH &&
y >= FACE_Y_POS && y <= FACE_Y_POS+FACE_BUTTON_HEIGHT)
onface = True;
if (op == 'u') {
if (!face_armed) return;
arm_face(False);
restart();
return;
}
if (op == 'd') {
if (!onface) return;
arm_face(True);
armed = False;
return;
}
if (onface != face_armed)
arm_face(onface);
}
void
arm_face(armit)
int armit;
{
face_armed = armit;
XClearArea(disp, win,
FACE_X_POS, FACE_Y_POS, FACE_BUTTON_WIDTH, FACE_BUTTON_HEIGHT,
False);
if (face_armed)
shadow_rev_rect(FACE_X_POS+2, FACE_Y_POS+2,
FACE_BUTTON_WIDTH-4, FACE_BUTTON_HEIGHT-4, 2);
else
shadow_rect(FACE_X_POS, FACE_Y_POS,
FACE_BUTTON_WIDTH, FACE_BUTTON_HEIGHT, 2);
draw_face();
}
void
mark_action(widget, event, args, num_args)
Widget widget;
XButtonEvent *event;
String *args;
int *num_args;
{
if (!game_on) return;
if (!layed_out) return;
if (!strcmp(args[0], "down")) {
int xg, yg;
xg = (event->x-SIDEMARGIN)/GSPACEX;
yg = (event->y-TOPMARGIN)/GSPACEY;
if (xg >= 0 && xg < gsizex &&
yg >= 0 && yg < gsizey) {
if (gridview[xg][yg] == UNCOVERED) return;
if (gridview[xg][yg] == MARKED) {
gridview[xg][yg] = (questions_allowed) ? QUESTIONED : COVERED;
marked_count--;
} else if (gridview[xg][yg] == QUESTIONED)
gridview[xg][yg] = COVERED;
else {
gridview[xg][yg] = MARKED;
marked_count++;
}
redrawsquare(xg, yg);
draw_digits(mine_count-marked_count, 0);
draw_digits(timer, 1);
}
}
}
void
clear_action(widget, event, args, num_args)
Widget widget;
XButtonEvent *event;
String *args;
int *num_args;
{
int xg, yg;
if (!game_on) return;
if (!layed_out) return;
xg = (event->x-SIDEMARGIN)/GSPACEX;
yg = (event->y-TOPMARGIN)/GSPACEY;
if (!(xg >= 0 && xg < gsizex && yg >= 0 && yg < gsizey))
return;
if (!strcmp(args[0], "down")) {
arm_clear(xg, yg, True);
armed_x = xg; armed_y = yg;
return;
}
if (!strcmp(args[0], "move")) {
int arm_it = (xg == armed_x && yg == armed_y);
if (arm_it != armed) arm_clear(armed_x, armed_y, arm_it);
return;
}
if (!armed) return;
arm_clear(armed_x, armed_y, False);
clear_around(xg, yg);
if (game_on)
set_face(FACE_HAPPY);
}
void
arm_clear(x, y, armit)
int x, y, armit;
{
int dx, dy;
armed = armit;
set_face(armit ? FACE_OHNO : FACE_HAPPY);
for (dx = -1; dx <= 1; dx++)
for (dy = -1; dy <= 1; dy++)
if (is_state(x+dx, y+dy, COVERED))
if (armit)
draw_blank_square(x+dx, y+dy, True);
else
draw_button(x+dx, y+dy);
}
void
draw_face()
{
int x, y;
x = (TOTAL_WIDTH-fillface_width)/2+face_armed;
y = (TOPMARGIN-fillface_height)/2+face_armed;
XSetClipMask(disp, gc, fillface);
XSetClipOrigin(disp, gc, x, y);
XSetBackground(disp, gc, cols[COL_YELLOW].pixel);
XSetForeground(disp, gc, cols[COL_BLACK].pixel);
XCopyPlane(disp,
(Drawable) faces[(face_armed) ? FACE_PRESS : cur_face],
win, gc, 0, 0,
fillface_width, fillface_height, x, y, 1L);
XSetClipMask(disp, gc, None);
}
void
set_face(f)
int f;
{
if (cur_face == f) return;
cur_face = f;
draw_face();
}
void
redraw_cb(drawing_a, client_data, cbs)
Widget drawing_a;
XtPointer client_data;
XmDrawingAreaCallbackStruct *cbs;
{
int x, y, w, h, xf, yf, xt, yt;
x = cbs->event->xexpose.x-SIDEMARGIN;
y = cbs->event->xexpose.y-TOPMARGIN;
w = cbs->event->xexpose.width;
h = cbs->event->xexpose.height;
xf = x/GSPACEX;
yf = y/GSPACEY;
xt = (x+w+GSPACEX-1)/GSPACEX;
yt = (y+h+GSPACEX-1)/GSPACEX;
for (x = xf; x <= xt; x++)
for (y = yf; y <= yt; y++)
drawsquare(x, y);
if (xf < 0 || yf < 0 || xt >= gsizex || yt >= gsizey) {
shadow_rect(0, 0, TOTAL_WIDTH, TOTAL_HEIGHT, 3);
shadow_rev_rect(SIDEMARGIN, TOPMARGIN,
TOTAL_WIDTH-SIDEMARGIN*2,
TOTAL_HEIGHT-(TOPMARGIN+BOTMARGIN), 3);
shadow_rev_rect(SIDEMARGIN, STATUS_Y_OFFSET,
TOTAL_WIDTH-SIDEMARGIN*2,
STATUS_HEIGHT, 3);
shadow_rect(FACE_X_POS, FACE_Y_POS,
FACE_BUTTON_WIDTH, FACE_BUTTON_HEIGHT, 2);
draw_face();
draw_digits(mine_count-marked_count, 0);
draw_digits(timer, 1);
}
}
void
redrawsquare(x, y)
int x, y;
{
XClearArea(disp, win, x*GSPACEX+SIDEMARGIN,
y*GSPACEY+TOPMARGIN, GSPACEX, GSPACEY, True);
}
void
redraw_all()
{
XClearArea(disp, win, SIDEMARGIN,
TOPMARGIN, GSPACEX*gsizex, GSPACEY*gsizey, True);
}
void
redraw_entire()
{
if (disp)
XClearArea(disp, win, 0, 0, TOTAL_WIDTH, TOTAL_HEIGHT, True);
}
void
shadow_rect(xp, yp, w, h, thick)
int xp, yp, w, h, thick;
{
int off = 0;
w--, h--;
while (thick--) {
XSetForeground(disp, gc, cols[COL_WHITE].pixel);
XDrawLine(disp, win, gc,
xp, yp+off, xp+w-off, yp+off);
XDrawLine(disp, win, gc,
xp+off, yp, xp+off, yp+h-off);
XSetForeground(disp, gc, cols[COL_DARKGRAY].pixel);
XDrawLine(disp, win, gc,
xp+off, yp+h-off, xp+w, yp+h-off);
XDrawLine(disp, win, gc,
xp+w-off, yp+off, xp+w-off, yp+h);
off++;
}
}
void
shadow_rev_rect(xp, yp, w, h, thick)
int xp, yp, w, h, thick;
{
int off = 0;
w--, h--;
xp -= thick; yp -= thick;
w += thick*2; h += thick*2;
while (thick--) {
XSetForeground(disp, gc, cols[COL_DARKGRAY].pixel);
XDrawLine(disp, win, gc,
xp, yp+off, xp+w-off, yp+off);
XDrawLine(disp, win, gc,
xp+off, yp, xp+off, yp+h-off);
XSetForeground(disp, gc, cols[COL_WHITE].pixel);
XDrawLine(disp, win, gc,
xp+off, yp+h-off, xp+w, yp+h-off);
XDrawLine(disp, win, gc,
xp+w-off, yp+off, xp+w-off, yp+h);
off++;
}
}
void
draw_button(xp, yp)
int xp, yp;
{
xp = xp*GSPACEX+SIDEMARGIN;
yp = yp*GSPACEY+TOPMARGIN;
shadow_rect(xp, yp, GSPACEX, GSPACEY, 2);
}
void
draw_blank_square(xp, yp, clr)
int xp, yp, clr;
{
xp = xp*GSPACEX+SIDEMARGIN;
yp = yp*GSPACEY+TOPMARGIN;
if (clr)
XClearArea(disp, win,
xp, yp, GSPACEX, GSPACEY, False);
XSetForeground(disp, gc, cols[COL_DARKGRAY].pixel);
XDrawLine(disp, win, gc,
xp, yp, xp+GSPACEX-1, yp);
XDrawLine(disp, win, gc,
xp, yp, xp, yp+GSPACEY-1);
}
void
drawsquare(x, y)
int x, y;
{
int xp, yp;
char buf[2];
int wid;
int color, yoffset = 0;
if (x < 0 || y < 0 || x >= gsizex || y >= gsizey) return;
buf[1] = 0;
xp = x*GSPACEX+SIDEMARGIN;
yp = y*GSPACEY+TOPMARGIN;
if (gridview[x][y] == UNCOVERED) {
draw_blank_square(x, y, False);
if (!grid[x][y]) return;
if (grid[x][y] == MINE) {
buf[0] = 'M';
color = COL_BLACK;
} else {
color = numcols[grid[x][y]-1];
buf[0] = grid[x][y]+'0';
yoffset = 2;
}
} else if (gridview[x][y] == MARKED) {
draw_button(x, y);
buf[0] = 'X';
color = COL_RED;
} else if (gridview[x][y] == QUESTIONED) {
draw_button(x, y);
buf[0] = '?';
color = COL_RED;
} else {
draw_button(x, y);
return;
}
wid = XTextWidth(font_info, buf, 1);
XSetForeground(disp, gc, cols[color].pixel);
XDrawString(disp, win, gc,
xp+(GSPACEX-wid)/2,
yp+(GSPACEY+font_info->ascent-font_info->descent)/2+yoffset,
buf, 1);
}
void
layout_board(fx, fy)
int fx, fy;
{
int i, x, y, xd, yd, tries;
srand((unsigned int) time(0));
for (i = 0; i != mine_count; i++) {
tries = 1000;
do {
x = (rand()>>1) % gsizex;
y = (rand()>>1) % gsizey;
tries--;
} while (tries && (grid[x][y] ||
!(x < fx-1 || x > fx+1 || y < fy-1 || y > fy+1)));
grid[x][y] = MINE;
if (!tries) {
mine_count = i;
break;
}
}
for (x = 0; x != gsizex; x++)
for (y = 0; y != gsizey; y++) {
if (grid[x][y] == MINE) continue;
i = 0;
for (xd = -1; xd <= 1; xd++)
for (yd = -1; yd <= 1; yd++)
if (hasmine(x+xd, y+yd)) i++;
grid[x][y] = i;
}
layed_out = 1;
if (timer_id)
XtRemoveTimeOut(timer_id);
timer_id = XtAppAddTimeOut(app, 1000L, (void_proc) timer_callback, NULL);
covered_count = gsizex*gsizey;
fix_size();
}
void
timer_callback()
{
if (!(layed_out && game_on)) {
timer_id = 0;
return;
}
if (timer >= 999) return;
draw_digits(++timer, 1);
timer_id = XtAppAddTimeOut(app, 1000L, (void_proc) timer_callback, NULL);
}
int
hasmine(x, y)
int x, y;
{
if (x < 0 || y < 0 || x >= gsizex || y >= gsizey) return False;
return grid[x][y] == MINE;
}
int
is_state(x, y, state)
int x, y, state;
{
if (x < 0 || y < 0 || x >= gsizex || y >= gsizey) return False;
return gridview[x][y] == state;
}
int
iscovered(x, y)
int x, y;
{
if (x < 0 || y < 0 || x >= gsizex || y >= gsizey) return False;
return gridview[x][y] == COVERED;
}
void
uncover(x, y)
int x, y;
{
int dx, dy;
if (x < 0 || y < 0 || x >= gsizex || y >= gsizey) return;
if (gridview[x][y] != COVERED) return;
gridview[x][y] = UNCOVERED;
covered_count--;
if (grid[x][y] == MINE)
boom();
else if (covered_count == mine_count)
winner();
redrawsquare(x, y);
if (grid[x][y] == 0)
for (dx = -1; dx <= 1; dx++)
for (dy = -1; dy <= 1; dy++)
uncover(x+dx, y+dy);
}
void
boom()
{
int x, y;
for (x = 0; x != gsizex; x++)
for (y = 0; y != gsizey; y++) {
if (grid[x][y] != MINE || gridview[x][y] == MARKED) continue;
gridview[x][y] = UNCOVERED;
redrawsquare(x, y);
}
game_on = 0;
relax_size();
set_face(FACE_DEAD);
}
void
winner()
{
int x, y;
game_on = 0;
relax_size();
for (x = 0; x != gsizex; x++)
for (y = 0; y != gsizey; y++)
if (gridview[x][y] == COVERED) {
gridview[x][y] = MARKED;
redrawsquare(x, y);
}
draw_digits(0, 0);
set_face(FACE_COOL);
XtAppAddTimeOut(app, 500L, (void_proc) new_best, (XtPointer) game_level);
}
void
restart()
{
int x, y;
for (x = 0; x != gsizex; x++)
for (y = 0; y != gsizey; y++) {
gridview[x][y] = COVERED;
grid[x][y] = 0;
}
game_on = 1;
layed_out = 0;
relax_size();
if (drawarea) {
redraw_all();
set_face(FACE_HAPPY);
}
timer = marked_count = 0;
}
void
clear_around(x, y)
int x, y;
{
int dx, dy, ct = 0;
if (gridview[x][y] != UNCOVERED) return;
for (dx = -1; dx <= 1; dx++)
for (dy = -1; dy <= 1; dy++)
if (is_state(x+dx, y+dy, MARKED)) ct++;
if (grid[x][y] != ct) return;
for (dx = -1; dx <= 1; dx++)
for (dy = -1; dy <= 1; dy++)
if (is_state(x+dx, y+dy, COVERED)) uncover(x+dx, y+dy);
}
XmString
genxmstr(str)
char *str;
{
static XmString oldstr;
if (oldstr) XmStringFree(oldstr);
return oldstr = XmStringLtoRCreate(str, XmSTRING_DEFAULT_CHARSET);
}
void
draw_hwedge(x, y, dir)
int x, y, dir;
{
int i;
for (i = 0; i <= 2; i++, y += dir)
XDrawLine(disp, win, gc, x+i, y, x+DIGIT_HWEDGE_WIDTH-(i+1), y);
}
void
draw_midwedge(x, y)
int x, y;
{
XDrawLine(disp, win, gc, x, y, x+DIGIT_HWEDGE_WIDTH-1, y);
XDrawLine(disp, win, gc, x+1, y+1, x+DIGIT_HWEDGE_WIDTH-2, y+1);
XDrawLine(disp, win, gc, x+1, y-1, x+DIGIT_HWEDGE_WIDTH-2, y-1);
}
void
draw_vwedge(x, y, dir)
int x, y, dir;
{
int i;
for (i = 0; i <= 2; i++, x += dir)
XDrawLine(disp, win, gc, x, y+i, x, y+DIGIT_VWEDGE_HEIGHT-(i+1));
}
void
draw_digit(val, num, which)
int val, num, which;
{
int x, y;
static int segs[11] = {
127-2, 32+64, 127-(8+64),
127-(8+16), 8+32+2+64, 127-(32+16),
127-32, 1+32+64, 127,
127-16, 2
};
int seg = segs[val];
x = !which ? DIGIT_X_OFFSET :
TOTAL_WIDTH-(DIGIT_X_OFFSET+DIGIT_COUNT*DIGIT_WIDTH);
x += num*DIGIT_WIDTH+DIGIT_MARGIN;
y = DIGIT_Y_OFFSET+DIGIT_MARGIN+1;
XSetForeground(disp, gc, cols[(seg & 1) ? COL_RED : COL_DARKRED].pixel);
draw_hwedge(x+1, y, 1);
XSetForeground(disp, gc, cols[(seg & 2) ? COL_RED : COL_DARKRED].pixel);
draw_midwedge(x+1, y+1+DIGIT_VWEDGE_HEIGHT);
XSetForeground(disp, gc, cols[(seg & 4) ? COL_RED : COL_DARKRED].pixel);
draw_hwedge(x+1, y+(1+DIGIT_VWEDGE_HEIGHT)*2, -1);
XSetForeground(disp, gc, cols[(seg & 8) ? COL_RED : COL_DARKRED].pixel);
draw_vwedge(x, y+1, 1);
XSetForeground(disp, gc, cols[(seg & 16) ? COL_RED : COL_DARKRED].pixel);
draw_vwedge(x, y+2+DIGIT_VWEDGE_HEIGHT, 1);
XSetForeground(disp, gc, cols[(seg & 32) ? COL_RED : COL_DARKRED].pixel);
draw_vwedge(x+1+DIGIT_HWEDGE_WIDTH, y+1, -1);
XSetForeground(disp, gc, cols[(seg & 64) ? COL_RED : COL_DARKRED].pixel);
draw_vwedge(x+1+DIGIT_HWEDGE_WIDTH, y+2+DIGIT_VWEDGE_HEIGHT, -1);
}
void
draw_digits(val, which)
int val, which;
{
XSetForeground(disp, gc, cols[COL_BLACK].pixel);
XFillRectangle(disp, win, gc,
!which ? DIGIT_X_OFFSET :
TOTAL_WIDTH-(DIGIT_X_OFFSET+DIGIT_COUNT*DIGIT_WIDTH),
DIGIT_Y_OFFSET,
DIGIT_WIDTH * DIGIT_COUNT, DIGIT_HEIGHT);
XSetForeground(disp, gc, cols[COL_RED].pixel);
if (val < 0) {
draw_digit(10, 0, which);
val = -val;
} else
draw_digit((val/100)%10, 0, which);
draw_digit((val/10)%10, 1, which);
draw_digit(val%10, 2, which);
}
void
set_level(w, level)
Widget w;
int level;
{
int i;
if (level == 1) {
mine_count = 10;
gsizex = gsizey = 8;
} else if (level == 2) {
mine_count = 40;
gsizex = gsizey = 16;
} else if (level == 3) {
mine_count = 99;
gsizex = 30;
gsizey = 16;
}
game_level = level-1;
if (!drawarea) return;
for (i = 0; i != XtNumber(level_buttons); i++)
if (i != level-1)
XmToggleButtonSetState(level_buttons[i], False, False);
XtVaSetValues(toplevel, XmNallowShellResize, True, NULL);
/*
printf("set_level: new XmNwidth=%4d, new XmNheight=%4d\n",
GSPACEX*gsizex+SIDEMARGIN*2,
GSPACEY*gsizey+TOPMARGIN+BOTMARGIN);
*/
XtVaSetValues(drawarea,
XmNwidth, GSPACEX*gsizex+SIDEMARGIN*2,
XmNheight, GSPACEY*gsizey+TOPMARGIN+BOTMARGIN,
NULL);
XtVaSetValues(toplevel, XmNallowShellResize, False, NULL);
redraw_entire();
restart();
}
void
tog_question()
{
questions_allowed ^= 1;
}
int dialog_up;
void
set_custom()
{
Widget custom, pane, w, rc, rc2, mine_w, height_w, width_w;
char buf[20];
custom = XtVaCreatePopupShell("Custom",
topLevelShellWidgetClass, toplevel,
XmNdeleteResponse, XmDESTROY,
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
NULL);
pane = XtVaCreateWidget(NULL, xmPanedWindowWidgetClass, custom,
XmNsashHeight, 1,
XmNsashWidth, 1,
NULL);
rc2 = XtVaCreateManagedWidget(NULL,
xmRowColumnWidgetClass, pane,
NULL);
rc = XtVaCreateManagedWidget(NULL,
xmRowColumnWidgetClass, rc2,
XmNorientation, XmHORIZONTAL,
NULL);
XtVaCreateManagedWidget("height_label",
xmLabelGadgetClass, rc,
NULL);
sprintf(buf, "%d", gsizey);
height_w = XtVaCreateManagedWidget("height_text",
xmTextFieldWidgetClass, rc,
XmNvalue, buf,
NULL);
rc = XtVaCreateManagedWidget(NULL,
xmRowColumnWidgetClass, rc2,
XmNorientation, XmHORIZONTAL,
NULL);
XtVaCreateManagedWidget("width_label",
xmLabelGadgetClass, rc,
NULL);
sprintf(buf, "%d", gsizex);
width_w = XtVaCreateManagedWidget("width_text",
xmTextFieldWidgetClass, rc,
XmNvalue, buf,
NULL);
rc = XtVaCreateManagedWidget(NULL,
xmRowColumnWidgetClass, rc2,
XmNorientation, XmHORIZONTAL,
NULL);
XtVaCreateManagedWidget("mines_label",
xmLabelGadgetClass, rc,
NULL);
sprintf(buf, "%d", mine_count);
mine_w = XtVaCreateManagedWidget("mines_text",
xmTextFieldWidgetClass, rc,
XmNvalue, buf,
NULL);
rc2 = XtVaCreateManagedWidget(NULL,
xmFormWidgetClass, pane,
NULL);
w = XtVaCreateManagedWidget("ok",
xmPushButtonWidgetClass, rc2,
XmNleftAttachment, XmATTACH_POSITION,
XmNrightAttachment,XmATTACH_POSITION,
XmNleftPosition, 30,
XmNrightPosition, 70,
NULL);
XtAddCallback(w, XmNactivateCallback, (void_proc) dialog_ok, NULL);
XtManageChild(pane);
XtPopup(custom, XtGrabExclusive);
dialog_up = True;
while (dialog_up) {
XtAppProcessEvent(app, XtIMAll);
XSync(disp, 0);
}
XtPopdown(custom);
get_text_int(width_w, &gsizex);
if (gsizex > 100) gsizex = 100;
if (gsizex < 8) gsizex = 8;
get_text_int(height_w, &gsizey);
if (gsizey > 100) gsizey = 100;
if (gsizey < 8) gsizey = 8;
get_text_int(mine_w, &mine_count);
if (mine_count < 1) mine_count = 1;
set_level((Widget) 0, 4);
}
void
dialog_ok()
{
dialog_up = False;
}
void
get_text_int(w, val)
Widget w;
int *val;
{
char *str;
str = XmTextFieldGetString(w);
if (!str) return;
if (atoi(str)) *val = atoi(str);
XtFree(str);
}
void
best_times()
{
Widget custom, pane, w, rc2, ok_w;
Widget matrix[9];
char buf[20];
struct scores *sc;
sc = get_scores();
custom = XtVaCreatePopupShell("Best",
topLevelShellWidgetClass, toplevel,
XmNdeleteResponse, XmDESTROY,
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
NULL);
pane = XtVaCreateWidget(NULL, xmPanedWindowWidgetClass, custom,
XmNsashHeight, 1,
XmNsashWidth, 1,
NULL);
XtVaCreateManagedWidget("label",
xmLabelGadgetClass, pane,
NULL);
rc2 = XtVaCreateManagedWidget(NULL,
xmFormWidgetClass, pane,
NULL);
matrix[0] = XtVaCreateManagedWidget("begin_label",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
NULL);
sprintf(buf, "%d", sc->times[0]);
matrix[1] = XtVaCreateManagedWidget("begin_time",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNlabelString, genxmstr(buf),
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
matrix[2] = XtVaCreateManagedWidget("begin_name",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, matrix[1],
XmNrightAttachment, XmATTACH_FORM,
XmNlabelString, genxmstr(sc->names[0]),
XmNleftOffset, 20,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
matrix[3] = XtVaCreateManagedWidget("inter_label",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, matrix[0],
XmNleftAttachment, XmATTACH_FORM,
NULL);
sprintf(buf, "%d", sc->times[1]);
matrix[4] = XtVaCreateManagedWidget("inter_time",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, matrix[0],
XmNleftAttachment, XmATTACH_WIDGET,
XmNleftWidget, matrix[3],
XmNleftOffset, 20,
XmNlabelString, genxmstr(buf),
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
XtVaSetValues(matrix[1], XmNleftWidget, matrix[4], NULL);
matrix[5] = XtVaCreateManagedWidget("inter_name",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, matrix[2],
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNleftWidget, matrix[2],
XmNrightAttachment, XmATTACH_FORM,
XmNlabelString, genxmstr(sc->names[1]),
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
matrix[6] = XtVaCreateManagedWidget("expert_label",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, matrix[3],
XmNleftAttachment, XmATTACH_FORM,
XmNbottomAttachment,XmATTACH_FORM,
NULL);
sprintf(buf, "%d", sc->times[2]);
matrix[7] = XtVaCreateManagedWidget("expert_time",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, matrix[4],
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNleftWidget, matrix[4],
XmNbottomAttachment,XmATTACH_FORM,
XmNlabelString, genxmstr(buf),
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
matrix[8] = XtVaCreateManagedWidget("expert_name",
xmLabelGadgetClass, rc2,
XmNtopAttachment, XmATTACH_WIDGET,
XmNtopWidget, matrix[5],
XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
XmNleftWidget, matrix[5],
XmNrightAttachment, XmATTACH_FORM,
XmNbottomAttachment,XmATTACH_FORM,
XmNlabelString, genxmstr(sc->names[2]),
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
rc2 = XtVaCreateManagedWidget(NULL,
xmFormWidgetClass, pane,
NULL);
ok_w = XtVaCreateManagedWidget("ok",
xmPushButtonWidgetClass, rc2,
XmNleftAttachment, XmATTACH_POSITION,
XmNrightAttachment,XmATTACH_POSITION,
XmNleftPosition, 0,
XmNrightPosition, 50,
NULL);
XtAddCallback(ok_w, XmNactivateCallback, (void_proc) dialog_ok, NULL);
w = XtVaCreateManagedWidget("clear",
xmPushButtonWidgetClass, rc2,
XmNleftAttachment, XmATTACH_POSITION,
XmNrightAttachment,XmATTACH_POSITION,
XmNleftPosition, 50,
XmNrightPosition, 100,
NULL);
XtAddCallback(w, XmNactivateCallback, (void_proc) clear_scores, NULL);
if (cant_write_score_file()) XtSetSensitive(w, False);
XtManageChild(pane);
XtPopup(custom, XtGrabExclusive);
XmProcessTraversal(ok_w, XmTRAVERSE_CURRENT);
dialog_up = True;
while (dialog_up) {
XtAppProcessEvent(app, XtIMAll);
XSync(disp, 0);
}
XtPopdown(custom);
}
void
about()
{
Widget custom, pane, w, rc2;
char buf[100];
custom = XtVaCreatePopupShell("About",
topLevelShellWidgetClass, toplevel,
XmNdeleteResponse, XmDESTROY,
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
NULL);
pane = XtVaCreateWidget(NULL, xmPanedWindowWidgetClass, custom,
XmNsashHeight, 1,
XmNsashWidth, 1,
NULL);
sprintf(buf, "xmine 1.0.%d by Paul Falstad", PATCHLEVEL);
XtVaCreateManagedWidget("label",
xmLabelGadgetClass, pane,
XmNlabelString, genxmstr(buf),
NULL);
rc2 = XtVaCreateManagedWidget(NULL,
xmFormWidgetClass, pane,
NULL);
w = XtVaCreateManagedWidget("ok",
xmPushButtonWidgetClass, rc2,
XmNleftAttachment, XmATTACH_POSITION,
XmNrightAttachment,XmATTACH_POSITION,
XmNleftPosition, 30,
XmNrightPosition, 70,
NULL);
XtAddCallback(w, XmNactivateCallback, (void_proc) dialog_ok, NULL);
XtManageChild(pane);
XtPopup(custom, XtGrabExclusive);
XmProcessTraversal(w, XmTRAVERSE_CURRENT);
dialog_up = True;
while (dialog_up) {
XtAppProcessEvent(app, XtIMAll);
XSync(disp, 0);
}
XtPopdown(custom);
}
void
get_score_file_name(buf)
char *buf;
{
if (*SCORE_FILE == '~' && getenv("HOME"))
sprintf(buf, "%s%s", getenv("HOME"), SCORE_FILE+1);
else
strcpy(buf, SCORE_FILE);
}
struct scores *
get_scores()
{
static struct scores sc;
char buf[1000];
int i, score;
FILE *in;
for (i = 0; i != 3; i++) {
strcpy(sc.names[i], "Anonymous");
sc.times[i] = 999;
}
get_score_file_name(buf);
if (in = fopen(buf, "r")) {
while (fscanf(in, "%d %d \"%[^\"]\"", &i, &score, buf) == 3) {
if (i < 0 || i > 2) break;
strcpy(sc.names[i], buf);
sc.times[i] = score;
}
fclose(in);
}
return ≻
}
void
write_scores(sc)
struct scores *sc;
{
int i;
char buf[1000];
FILE *out;
get_score_file_name(buf);
if (!(out = fopen(buf, "w")))
return;
for (i = 0; i != 3; i++)
if (sc->times[i] != 999)
fprintf(out, "%d %d \"%s\"\n", i, sc->times[i], sc->names[i]);
fclose(out);
}
void
new_best(level)
int level;
{
Widget custom, pane, rc2, name_w, w;
char *str;
struct scores *sc;
if (level < 0 || level >= 3) return;
sc = get_scores();
if (timer >= sc->times[level]) return;
custom = XtVaCreatePopupShell("HighScorer",
topLevelShellWidgetClass, toplevel,
XmNdeleteResponse, XmDESTROY,
XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL,
NULL);
pane = XtVaCreateWidget(NULL, xmPanedWindowWidgetClass, custom,
XmNsashHeight, 1,
XmNsashWidth, 1,
NULL);
XtVaCreateManagedWidget("label",
xmLabelGadgetClass, pane,
NULL);
name_w = XtVaCreateManagedWidget("name",
xmTextFieldWidgetClass, pane, NULL);
XtAddCallback(name_w, XmNactivateCallback, (void_proc) dialog_ok, NULL);
rc2 = XtVaCreateManagedWidget(NULL,
xmFormWidgetClass, pane,
NULL);
w = XtVaCreateManagedWidget("ok",
xmPushButtonWidgetClass, rc2,
XmNleftAttachment, XmATTACH_POSITION,
XmNrightAttachment,XmATTACH_POSITION,
XmNleftPosition, 30,
XmNrightPosition, 70,
NULL);
XtAddCallback(w, XmNactivateCallback, (void_proc) dialog_ok, NULL);
XtManageChild(pane);
XtPopup(custom, XtGrabExclusive);
XmTextFieldSetSelection(name_w, 0, XmTextFieldGetLastPosition(name_w),
CurrentTime);
XmProcessTraversal(name_w, XmTRAVERSE_CURRENT);
dialog_up = True;
while (dialog_up) {
XtAppProcessEvent(app, XtIMAll);
XSync(disp, 0);
}
XtPopdown(custom);
str = XmTextFieldGetString(name_w);
if (str && *str) {
strcpy(sc->names[level], str);
sc->times[level] = timer;
write_scores(sc);
}
if (str) XtFree(str);
best_times();
}
void
clear_scores()
{
char buf[1000];
FILE *out;
dialog_up = False;
get_score_file_name(buf);
if (out = fopen(buf, "w")) fclose(out);
}
int
cant_write_score_file()
{
return geteuid() != getuid();
}
void
fix_size()
{
XSizeHints hints;
Dimension wid, hgt;
XtVaGetValues(toplevel,
XmNwidth, &wid,
XmNheight, &hgt,
NULL);
hints.flags = PMaxSize|PMinSize;
hints.max_width = hints.min_width = wid;
hints.max_height = hints.min_height = hgt;
XSetWMNormalHints(disp, XtWindow(toplevel), &hints);
}
void
relax_size()
{
XSizeHints hints;
Dimension wid, hgt, menu_hgt;
XtVaGetValues(toplevel,
XmNwidth, &wid,
XmNheight, &hgt,
NULL);
hints.flags = PMaxSize|PMinSize|PResizeInc;
XtVaGetValues(menubar,
XmNheight, &menu_hgt,
NULL);
hints.min_width = SIDEMARGIN*2+GSPACEX*INITIAL_SIZE_X;
hints.min_height = TOPMARGIN+BOTMARGIN+menu_hgt+GSPACEY*INITIAL_SIZE_Y;
hints.max_width = hints.max_height = 10000;
hints.width_inc = GSPACEX;
hints.height_inc = GSPACEY;
XSetWMNormalHints(disp, XtWindow(toplevel), &hints);
}
void
resize_handler(w, data, event, contflag)
Widget w;
XtPointer data;
XEvent *event;
Boolean *contflag;
{
int new_gsizex, new_gsizey;
static int started = 0;
if (!started) {
started = 1;
relax_size();
}
if (event->type != ConfigureNotify) return;
if (layed_out && game_on) return;
/*
printf(
"resize_handler: event->xconfigure.width=%4d, event.xconfigure.height=%4d\n",
event->xconfigure.width,
event->xconfigure.height);
*/
new_gsizex = (event->xconfigure.width-SIDEMARGIN*2 + (GSPACEX-1)) / GSPACEX;
new_gsizey = (event->xconfigure.height-
(TOPMARGIN+BOTMARGIN) + (GSPACEY-1)) / GSPACEY;
/*
printf(
"resize_handler: gsizex=%2d, new_gsizex=%2d; gsizey=%2d, new_gsizey=%2d\n",
gsizex, new_gsizex, gsizey, new_gsizey);
*/
if (new_gsizex > MAX_GSIZEX)
new_gsizex = MAX_GSIZEX;
if (new_gsizey > MAX_GSIZEY)
new_gsizey = MAX_GSIZEY;
if (new_gsizex != gsizex || new_gsizey != gsizey) {
gsizex = new_gsizex;
gsizey = new_gsizey;
set_level(w, 4);
}
}